require File.dirname(__FILE__)+"/../../../test_helper"
require "starframe/sprite"
require "starframe/sprite/collision"
require "starframe/sprite/collision/dot"
require "starframe/sprite/collision/circle"
require "starframe/sprite/collision/rect"

class TestStarFrameSpriteCollisionRect < Test::Unit::TestCase
  class TestSprite < StarFrame::Sprite
    @texture = StarRuby::Texture.load "test"
  end
  def setup
    @sprite1 = TestSprite.new(0, 0)
    @sprite2 = TestSprite.new(0, 0)
  end
  
  def test_collide_rect_rect
    rect1 = StarFrame::Sprite::Collision::Rect.new(@sprite1, nil, 0, 0, 2, 2)
    rect2 = StarFrame::Sprite::Collision::Rect.new(@sprite2, nil, 1, 1, 2, 2)
    
    (-3..3).each do |@sprite2.x|
      (-3..3).each do |@sprite2.y|
        result = ((-3..1) === @sprite2.x && (-3..1) === @sprite2.y)
        assert_equal result, rect1.collide?(rect2), "#{@sprite2.x},#{@sprite2.y}"
        assert_equal result, rect2.collide?(rect1), "#{@sprite2.x},#{@sprite2.y}"
      end
    end
  end
  
  def test_collides_rect_dot
    rect1 = StarFrame::Sprite::Collision::Rect.new(@sprite1, nil, 0, 0, 1, 1)
    dot2  = StarFrame::Sprite::Collision::Dot.new(@sprite2, nil, 0, 0)
    (-3..3).each do |@sprite2.x|
      (-3..3).each do |@sprite2.y|
        result = ((0..1) === @sprite2.x && (0..1) === @sprite2.y)
        assert_equal result, rect1.collide?(dot2), "#{@sprite2.x},#{@sprite2.y}"
        assert_equal result, dot2.collide?(rect1), "#{@sprite2.x},#{@sprite2.y}"
      end
    end
  end
  
  def test_collides_rect_circle
    rect1   = StarFrame::Sprite::Collision::Rect.new(@sprite1, nil, 0, 0, 1, 1)
    circle2 = StarFrame::Sprite::Collision::Circle.new(@sprite2, nil, 0, 0, 1)
    (-3..3).each do |@sprite2.x|
      (-3..3).each do |@sprite2.y|
        result = ((-1..2) === @sprite2.x && (-1..2) === @sprite2.y)
        if result
          if (@sprite2.x == -1 && @sprite2.y == -1) ||
             (@sprite2.x == -1 && @sprite2.y ==  2) ||
             (@sprite2.x ==  2 && @sprite2.y == -1) ||
             (@sprite2.x ==  2 && @sprite2.y ==  2)
            result = false
          end
        end
        assert_equal result, rect1.collide?(circle2), "#{@sprite2.x},#{@sprite2.y}"
        assert_equal result, circle2.collide?(rect1), "#{@sprite2.x},#{@sprite2.y}"
      end
    end
  end
end
__END__
  def test_collide_true
    collisions = [
      StarFrame::Sprite::Collision::Dot.new(Vector[0, 0]),
      StarFrame::Sprite::Collision::Circle.new(Vector[0, 0], 1),
      StarFrame::Sprite::Collision::Rect.new(Vector[0, 0], Vector[1, 1]),
    ]
    
    collisions.each do |collision1|
      collisions.each do |collision2|
        assert_equal true, collision1.collide?(collision2), "#{collision1.class} / #{collision2.class}"
        assert_equal true, collision2.collide?(collision1), "#{collision2.class} / #{collision1.class}"
      end
    end
  end
  
  def test_collide_false
    collisions = [
      StarFrame::Sprite::Collision::Dot.new(Vector[0, 0]),
      StarFrame::Sprite::Collision::Circle.new(Vector[10, 0], 1),
      StarFrame::Sprite::Collision::Rect.new(Vector[20, 0], Vector[1, 1]),
    ]
    
    collisions.each do |collision1|
      collisions.each do |collision2|
        next if collision1 == collision2
        assert_equal false, collision1.collide?(collision2), "#{collision1.class} / #{collision2.class}"
        assert_equal false, collision2.collide?(collision1), "#{collision2.class} / #{collision1.class}"
      end
    end
  end
  
  def test_collide_none
    none = TestCollision.new
    collisions = [
      StarFrame::Sprite::Collision::Dot.new(Vector[0, 0]),
      StarFrame::Sprite::Collision::Circle.new(Vector[10, 0], 1),
      StarFrame::Sprite::Collision::Rect.new(Vector[20, 0], Vector[1, 1]),
    ]
    
    collisions.each do |collision|
      assert_equal true, collision.collide?(none)
      assert_nil         none.collide?(collision)
    end
  end
  
  def test_dot_dot
    dot1 = StarFrame::Sprite::Collision::Dot.new(Vector[0, 0])
    dot2 = StarFrame::Sprite::Collision::Dot.new(Vector[1, 0])
    assert_equal false, dot1.collide?(dot2)
    assert_equal false, dot2.collide?(dot1)
  end
  
  def test_circle_circle
    circle1 = StarFrame::Sprite::Collision::Circle.new(Vector[0, 0], 1)
    circle2 = StarFrame::Sprite::Collision::Circle.new(Vector[2, 2], 1)
    assert_equal false, circle1.collide?(circle2)
    assert_equal false, circle2.collide?(circle1)
  end
  
  def test_rect_rect
    rect1 = StarFrame::Sprite::Collision::Rect.new(Vector[0, 0], Vector[2, 2])
    rect2 = StarFrame::Sprite::Collision::Rect.new(Vector[3, 2], Vector[2, 2])
    assert_equal false, rect1.collide?(rect2)
    assert_equal false, rect2.collide?(rect1)
  end
end
